"""
ThreadPoolExecutor线程池

线程池：
    1.可以在主线程中获取某一个线程的状态或者某一个任务的状态以及返回值。
    2.当一个线程完成的时候我们主线程能立即知道。
    3.futures可以让多线程多进程编码接口一致。

"""

import time
from concurrent.futures import ThreadPoolExecutor, as_completed, wait


def get_html(times):
    time.sleep(times)
    print("get_html get page {} success".format(times))
    return times


def use_thread_pool_executor():
    executor = ThreadPoolExecutor(max_workers=2)
    # 通过submit函数提交执行的函数到线程池中，submit是立即返回
    task1 = executor.submit(get_html, (3))
    task2 = executor.submit(get_html, (2))

    # done方法用于判定某个事务是否完成（非阻塞）
    print(task1.done())
    if not task2.done():
        print(task2.cancel())

    time.sleep(3)
    print(task1.done())
    # result方法可以获取task的执行结果（阻塞）
    result = task1.result()
    print(result)
    # 输出结果：
    """
    False
    False
    get_html get page 2 success
    get_html get page 3 success
    False
    3
    """


def use_thread_pool_executor_batch():
    executor = ThreadPoolExecutor(max_workers=2)
    urls = [1, 2, 4]
    all_task = [executor.submit(get_html, (url)) for url in urls]

    # 获取已成功的task的返回
    for future in as_completed(all_task):
        data = future.result()
        print("use_thread_pool_executor_batch get page {} success".format(data))

    # 等待所有task执行完成
    wait(all_task)
    print("执行完毕")
    # 输出结果：
    """
    get_html get page 1 success
    use_thread_pool_executor_batch get page 1 success
    get_html get page 2 success
    use_thread_pool_executor_batch get page 2 success
    get_html get page 4 success
    use_thread_pool_executor_batch get page 4 success
    执行完毕
    """


def use_thread_pool_executor_map():
    executor = ThreadPoolExecutor(max_workers=2)
    urls = [1, 2, 4]

    # 通过executor获取已经完成的task的值，执行顺序和urls里的顺序一致
    for data in executor.map(get_html, urls):
        print("use_thread_pool_executor_map get page {} success".format(data))
        # 输出结果：
        """
        get_html get page 1 success
        use_thread_pool_executor_map get page 1 success
        get_html get page 2 success
        use_thread_pool_executor_map get page 2 success
        get_html get page 4 success
        use_thread_pool_executor_map get page 4 success
        """


if __name__ == '__main__':
    # use_thread_pool_executor()
    use_thread_pool_executor_batch()
    # use_thread_pool_executor_map()
